#include <cmath>
#include <iomanip>
#include <iostream>

// China Transformed
namespace gcj02
{
    /// 克拉索夫斯基椭球参数
    constexpr double GCJ_A = 6378245;
    constexpr double GCJ_EE = 0.00669342162296594323; // f = 1/298.3; e^2 = 2*f - f**2
    constexpr double PI = 3.14159265358979323846;
    // 精度控制（最大误差）
    constexpr double g2w_precision = 1.0 / 111391.0;

    struct CoordGGA;

    struct Coord
    {
        // DD.XXX           114.15829
        double lon = 0.0; // 经度
        double lat = 0.0; // 纬度
        Coord() {};
        Coord(double lon_, double lat_) : lon(lon_), lat(lat_) {};
        Coord(const CoordGGA&);
        Coord(const Coord&);
        void operator=(const CoordGGA&);
    };

    struct CoordGGA
    {
        // DDFF.MM           11410.30162
        double lon = 0.0; // 经度
        double lat = 0.0; // 纬度

        CoordGGA() {};
        CoordGGA(double lon_, double lat_) : lon(lon_), lat(lat_) {};
        CoordGGA(const Coord&);
        CoordGGA(const CoordGGA&);
        void operator=(const Coord&);
    };

    double formGGA(double gga);
    double toGGA(double gga);

    bool OutOfChina(Coord coords);
    Coord WGS84ToGCJ02(Coord wgs, bool checkChina = true);

    // 计算两个坐标值的偏差值
    Coord DiffCoord(Coord a, Coord b);

    Coord GCJ02ToWGS84(Coord gcj, bool checkChina = true);

    inline std::ostream &
    operator<<(std::ostream &__out, Coord gga)
    {
        __out << "Coord: { " << std::fixed << std::setprecision(5) << gga.lon << ", " << gga.lat << " }";
        return __out;
    }

    inline std::ostream &
    operator<<(std::ostream &__out, CoordGGA gga)
    {
        __out << "CoordGGA: { " << std::fixed << std::setprecision(5) << gga.lon << ", " << gga.lat << " }";
        return __out;
    }

}